#ifndef MINICLOUD_H
#define MINICLOUD_H

#include "MiniObject.h"
#include "MiniBSplineCurve.h"
#include "MiniBSplineSurface.h"

namespace XYF
{
    /**
     * @file: MiniCloud.h
     * @author: xingyifan
     * @date: 2023-03-10 21:39
     *
     * @description: 三维点云
     */

    class MiniCloud : public MiniObject
    {
    public:
        MiniCloud(const MiniArray<Vector3f> &points);

        // 重载返回类型
        virtual int GetType() override;

        int GetPointsNum() const;                     // 获得顶点数
        const MiniArray<Vector3f> &GetPoints() const; // 获得顶点数组的引用
        MiniArray<Vector3f> &GetPoints();             // 获得顶点数组

        // 最小二乘法+能量项曲面拟合/最小化弦长及平滑化拟合/边界曲线参数化方法
        MiniBSplineSurface *EnergyFittingSurface(MiniArray<Real> &u, MiniArray<Real> &v, int Nu, int Nv, int p, int q, MiniArray<Real> &w, Real alpha, Real beta) const;
        MiniBSplineSurface *ChordFittingSurface(MiniArray<Real> &u, MiniArray<Real> &v, int Nu, int Nv, int p, int q, MiniArray<Real> &w, Real alpha, Real beta) const;
        MiniBSplineSurface *BoundaryParameterization(MiniArray<Real> &u, MiniArray<Real> &v, int Nu, int Nv, int p, int q, MiniArray<Real> &w, Real alpha, Real beta) const;

        // 增量几何迭代法的曲面拟合
        MiniBSplineSurface *LSPIASurface(MiniArray<Real> &u, MiniArray<Real> &v, int Nu, int Nv, int p, int q, Real tol) const;

        // 获得 Nu * Nv 个控制点的初始投影曲面，tol 设置每步下降的误差，ru, rv 设置包围盒伸缩比例
        MiniBSplineSurface *SDEInitialDBS(int Nu, int Nv, int p, int q, Real tol, Real ru = 1, Real rv = 1) const;

    protected:
        MiniArray<Vector3f> m_points; // 保存点的数组
    };
}

#endif // MINICLOUD_H
